#include "wav_file.h"

#include "string.h"

/**
 * @fn        checkWave
 * @brief    Check if file is in correct format
 * @param fp -file handle, already opened
 * @note    only support 16bit/singlechannel/32000/16bit/PCM wave format
 * @return avaliable samples in file
 */
int checkWav(FIL *fp)
{
    int len;
    RiffHeader riffHeader;
    FmtBlock fmtBlock;
    DataBlock dataBlock;


    if( FR_OK != f_read(fp, &riffHeader, sizeof(riffHeader), &len) )
    {
        return -1;
    }

    if( len !=sizeof(riffHeader) || memcmp(riffHeader.szRiffID, "RIFF",  4) || memcmp(riffHeader.szRiffFormat, "WAVE", 4) )
    {
        return -1;
    }

    /// do not read pad
    if(FR_OK != f_read(fp, &fmtBlock, sizeof(fmtBlock)-2, &len) )
    {
        return -2;
    }

    if(len != sizeof(fmtBlock)-2 || memcmp(fmtBlock.szFmtID, "fmt ", 4) )
    {
        return -2;
    }

    /// check format 
    if( fmtBlock.wavFormat.wFormatTag !=0x1 || fmtBlock.wavFormat.wChannels !=1 || fmtBlock.wavFormat.dwSamplesPerSec !=32000 || fmtBlock.wavFormat.wBlockAlign !=2)
    {
        return -3;
    }

    if(fmtBlock.dwFmtSize ==18)
    {
        if(FR_OK != f_read(fp, &fmtBlock.wavFormat.pack, 2, &len))
        {
            return -3;
        }
    }
    else if(fmtBlock.dwFmtSize !=16)
    {
       return -3;
    }

    if(FR_OK != f_read(fp, &dataBlock, sizeof(dataBlock), &len) )
    {
        return -4;
    }

    //check fact or data
    if( 0==memcmp(dataBlock.szDataID, "fact",4)  )
    {
        if(FR_OK !=f_read(fp, &dataBlock, 4,&len) )
        {
            return -5;
        }
        if(FR_OK != f_read(fp, &dataBlock, sizeof(dataBlock), &len) )
        {
        	return -5;
        }

    }

    if(memcmp(dataBlock.szDataID, "data",4) || len!=sizeof(dataBlock) )
    {
        return -6;
    }

    return dataBlock.dwDataSize;
}

/**
 * @fn        getWave
 * @brief    get wave samples from fp
 * @param  len -number of samples
 * @return  available samples in buffer
 */
int getWave(FIL *fp, short *buffer, int len)
{
    int t_len;

    if( FR_OK != f_read(fp, (char *)buffer, len*2, &t_len) )
    {
        return -1;
    }

    return t_len/2;
}

